package com.tale.springbootatm.controller;

import com.tale.springbootatm.common.constant.StatusCode;
import com.tale.springbootatm.common.enums.MessageEnum;
import com.tale.springbootatm.common.rabbit.RabbitSender;
import com.tale.springbootatm.common.util.MD5Util;
import com.tale.springbootatm.common.util.R;
import com.tale.springbootatm.entity.PasswordError;
import com.tale.springbootatm.entity.TransactionRecord;
import com.tale.springbootatm.entity.User;
import com.tale.springbootatm.dao.PasswordErrorRep;
import com.tale.springbootatm.dao.TransactionRecordRep;
import com.tale.springbootatm.service.UserService;
import com.tale.springbootatm.common.vo.MessageVO;
import com.tale.springbootatm.common.vo.ParamsVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.util.Date;

/**
 * author: 蔡奇峰
 * date: 2020/4/11 14:26
 *
 * @Version V1.0
 **/
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Autowired
    private UserService service;
    @Autowired
    private PasswordErrorRep passwordErrorRep;
    @Autowired
    private TransactionRecordRep transactionRecordRep;
    @Autowired
    private RabbitSender rabbitSender;

    /**
     * 余额查询
     *
     * @param user
     * @return
     */
    @PostMapping("/balance")
    public R balanceQuery(@RequestBody User user) {
        if (ObjectUtils.isEmpty(user)) {
            return R.fail().code(StatusCode.OBJECT_NULL).message(StatusCode.OBJECT_NULL_MSG);
        }
        long bankCard = user.getBankCard();
        User one = service.getOne(bankCard);

        if (ObjectUtils.isEmpty(one)) {
            return R.fail().message(StatusCode.OBJECT_NULL_MSG).code(StatusCode.OBJECT_NULL);
        }

        return R.success().data("balance", one.getBalance());
    }


    /**
     * 取款
     * 参数包含：卡号和取款金额
     *
     * @param transaction
     * @return
     */
    @PostMapping("/take")
    public R withdrawMoney(@RequestBody TransactionRecord transaction) {
        long bankCard = transaction.getBankCard();
        // 取款金额
        double amount = transaction.getAmount();
        if (amount <= 0) {
            return R.fail().message(StatusCode.TAKE_MONEY_ERROR);
        }

        User one = service.getOne(bankCard);
        if (ObjectUtils.isEmpty(one)) {
            return R.fail().message(StatusCode.TAKE_NULL);
        }

        // 账户余额
        double balance = one.getBalance();
        // 余额不足
        if (balance - amount < 0) {

            return R.fail().message(StatusCode.NOT_MONEY);
        }
        balance = balance - amount;

        // 扣钱
        int flag = service.updateBalance(bankCard, balance);
        if (flag < 0) {
            return R.fail().message("取款失败！请到柜台询问具体缘由");
        }
        Date nowDate = new Date();
        transaction.setTransactionDate(nowDate);
        String money = "-" + amount;
        transaction.setMoney(money);

        // 保存交易记录
        transactionRecordRep.save(transaction);

        return R.success().message(StatusCode.TAKE_SUCCESS).code(StatusCode.TAKE_MONEY);
    }

    /**
     * 插卡 并记录密码错误
     *
     * @param user
     * @return
     */
    @PostMapping("/login")
    public R login(@RequestBody User user) {
        String password = user.getPassword();
        // 密码加密
        password = MD5Util.saltEncrypted(password);

        System.out.println("pwd---->" + password);

        long bankCard = user.getBankCard();

        User one = service.findOne(bankCard, password);
        // 获取当前时间
        Date date = new Date();

        // 卡号或密码错误
        if (ObjectUtils.isEmpty(one)) {
            User oneUser = service.getOne(bankCard);

            // 卡号不存在
            if (ObjectUtils.isEmpty(oneUser)) {
                return R.fail().message(StatusCode.NOT_FOUND_CARD).code(MessageEnum.CARD_NOT_EXISTS.code());
            }
            // 密码错误
            PasswordError pwdError = new PasswordError(bankCard, date);

            // 保存密码错误记录
            passwordErrorRep.save(pwdError);

            // 判断是否锁卡
            boolean forbidden = forbidden(bankCard);
            if (forbidden) {
                return R.fail().message(StatusCode.LOCK_CARD).code(StatusCode.LOCK_STATUS);
            }

            return R.fail().message(StatusCode.PWD_ERROR).code(StatusCode.PASSWORD_ERROR);
        }


        // 判断是否锁卡
        boolean forbidden = forbidden(bankCard);
        if (forbidden) {
            return R.fail().message(StatusCode.LOCK_CARD).code(StatusCode.LOCK_STATUS);
        }

        int flag = service.updateLoginDate(one.getBankCard(), date);

//        if (flag < 1){
//            return R.fail().message("登录失败！请到柜台询问具体缘由");
//        }

        return R.success();
    }


    /**
     * 模拟锁卡
     * 判断是否锁卡
     *
     * @param bankCard
     */
    public boolean forbidden(long bankCard) {
        int count = passwordErrorRep.countByBankCard(bankCard);
        if (count >= 3) {
            // 更新卡号状态
            service.updateType(bankCard, 3);

            return true;
        }

        return false;
    }


    /**
     * 修改密码
     *
     * @param paramsVO
     * @return
     */
    @PostMapping("/password")
    public R updatePassword(@RequestBody ParamsVO paramsVO) {
        if (ObjectUtils.isEmpty(paramsVO)) {
            return R.fail().message(StatusCode.UPDATE_PASSWORD_ERROR);
        }

        int bankCard = paramsVO.getBankCard();
        String password = paramsVO.getPassword();
        // 密码加密
        password = MD5Util.saltEncrypted(password);

        User one = service.findOne(bankCard, password);
        if (ObjectUtils.isEmpty(one)) {
            return R.fail().message(StatusCode.PWD_ERROR);
        }

        String newPassword = paramsVO.getNewPassword();

        // 密码加密
        newPassword = MD5Util.saltEncrypted(newPassword);

        int flag = service.updatePassword(bankCard, newPassword);
        if (flag <= 0) {
            return R.fail().message(StatusCode.UPDATE_PASSWORD_ERROR);
        }
        MessageVO messageVO = new MessageVO();
        messageVO.setPassword(paramsVO.getPassword());
        messageVO.setBankCard(bankCard);
        messageVO.setMail(one.getMail());

        log.info("修改密码--》", messageVO.toString());

        rabbitSender.send(messageVO);

        return R.success().message(StatusCode.UPDATE_PASSWORD_SUCCESS);
    }
}
